#include <iostream>
#include <string>
#include <fstream>
#include "Almacenamiento.h"

void EstrategiaAlmacenamientoBloques::abrir(Almacenamiento * almacenamiento) {
	cout << "Abrir en estrategia de almacenamiento" << endl;
	Metadata* meta;
	meta = almacenamiento->abrir('b');
	if (meta != NULL && meta->getTipo() != 'b') {
		almacenamiento->setExisteMetadata(true);
		almacenamiento->setMetadata(meta);
	} else if (meta == NULL) {
		almacenamiento->setExisteMetadata(false);
		almacenamiento->inicializarMetadata('b');
	} else {
		almacenamiento->cerrar();//cierra ambos
		throw 1;
	}
}

void EstrategiaAlmacenamientoBloques::cerrar(Almacenamiento * almacenamiento) {
	almacenamiento->cerrar();
}

int EstrategiaAlmacenamientoBloques::almacenar(Almacenamiento * almacenamiento,
		Registro registro) {
	cout << "Va a buscar espacio libre" << endl;
	int nBloque = almacenamiento->buscarEspacioLibre(registro.getTamanio());
	Bloque* bloque;
	if(nBloque == -1){
		bloque = new Bloque(almacenamiento->getLongBloque());
	} else {
		Componente* c = almacenamiento->leer(nBloque);
		bloque = dynamic_cast<Bloque*> (c);
	}

	bloque->addComponente(registro);

	return almacenamiento->escribir(*bloque, nBloque);
}

Registro EstrategiaAlmacenamientoBloques::recuperar(
		Almacenamiento* almacenamiento, int nbloque, list<string> claves) {

	Componente* comp = almacenamiento->leer(nbloque);
	Bloque* bloque = dynamic_cast<Bloque*>(comp);

	int pos = bloque->Compuesto::buscarComponente(claves);
	if (pos != -1)
		return bloque->getComponente(pos);
	else
		throw 1;

}

void EstrategiaAlmacenamientoBloques::modificar(Almacenamiento * almacenamiento,
		Registro componente, int nbloque) {

	list<string> claves = componente.getValoresClaves();

	Componente* comp = almacenamiento->leer(nbloque);
	Bloque* bloque = dynamic_cast<Bloque*>(comp);

	int pos = bloque->Compuesto::buscarComponente(claves);
	if (pos == -1)
		throw 1;

	bloque->borrarComponente(pos);
	bloque->addComponente(componente);

	almacenamiento->escribir(*bloque, nbloque);
}

void EstrategiaAlmacenamientoBloques::borrar(Almacenamiento * almacenamiento,
		int nbloque, list<string> claves) {

	Componente* comp = almacenamiento->leer(nbloque);
	Bloque* bloque = dynamic_cast<Bloque*>(comp);

	int pos = bloque->Compuesto::buscarComponente(claves);
	if (pos == -1)
		throw 1;

	bloque->borrarComponente(pos);

	almacenamiento->escribir(*bloque, nbloque);

}

void EstrategiaAlmacenamientoBloques::borrar(Almacenamiento* almacenamiento,Registro componente){

}

void EstrategiaAlmacenamientoBloques::imprimir(Almacenamiento* almacenamiento){

}
